%% Rules used to check the consistency between the anti-erosion specifications.

:- discontiguous(must_dependency/3).
:- discontiguous(onlycan_dependency/3).
:- discontiguous(cannot_dependency/3).

must_dependency('derives','View','Model').
cannot_dependency('derives','View','Model').

%% FUNCTIONS
%%
allowing_dependency_rule(RELATION,CONCEPT_A,CONCEPT_B) :- 
	must_dependency(RELATION,CONCEPT_A,CONCEPT_B).
	
allowing_dependency_rule(RELATION,CONCEPT_A,CONCEPT_B) :- 
	onlycan_dependency(RELATION,CONCEPT_A,CONCEPT_B).

forbid_rule(X,Y,Z) :- cannot_dependency(X,Y,Z).
 
%% checa incosistencia do tipo A deve/apenas pode acessar B e A nao pode acessar B
inconsistent_forbid_allow_rules(RELATION, CONCEPT_A, CONCEPT_B) :-
	 forbid_rule(RELATION,CONCEPT_A,CONCEPT_B),
	 allowing_dependency_rule(RELATION,CONCEPT_A,CONCEPT_B).
	 
%% only A can-depend C
%% only B can-depend C inconsistent	 
inconsistent_onlycan_rules(RELATION, CONCEPT_A, CONCEPT_B) :-
		 onlycan_dependency(RELATION, CONCEPT_A, CONCEPT_C),
		 onlycan_dependency(RELATION, CONCEPT_B, CONCEPT_C),
		 CONCEPT_A \== CONCEPT_B.


%% analysis of cyclic_dependencies lenght 2
%% recursive analysis takes so much memory
cyclic_dependencies(RELATION,[CA, CB]):-
		allowing_dependency_rule(RELATION, CA, CB),
		allowing_dependency_rule(RELATION, CB, CA),
		CA \== CB.	 
		
%% analysis of cyclic_dependencies lenght 3
cyclic_dependencies(RELATION,[CA, CB, CC]):-
		allowing_dependency_rule(RELATION, CA, CB),
		allowing_dependency_rule(RELATION, CB, CC),
		allowing_dependency_rule(RELATION, CC, CA),
		CA \== CB,
		CB \== CC,
		CC \== CA.		
		
%% analysis of cyclic_dependencies lenght 4
cyclic_dependencies(RELATION,[CA, CB, CC, CD]):-
		allowing_dependency_rule(RELATION, CA, CB),
		allowing_dependency_rule(RELATION, CB, CC),
		allowing_dependency_rule(RELATION, CC, CD),
		allowing_dependency_rule(RELATION, CD, CA),
		CA \== CB,
		CA \== CC,
		CA \== CD,
		CB \== CC,
		CB \== CD,
		CC \== CD.		
				